import jwt from 'jsonwebtoken';
import type { User } from '@prisma/client';
import type { AuthUser } from '../types/express';
import { testConfig } from '../config/testConfig';
import { UserRole } from '../types/prisma-types';
import type { PrismaClient } from '@prisma/client';

export function createTestToken(user: User): string {
  const payload = {
    id: user.id,
    email: user.email,
    role: user.role,
    name: user.name
  };
  return jwt.sign(payload, testConfig.jwt.secret, { expiresIn: '1h' });
}

export function createTestUser(overrides: Partial<User> = {}): User {
  return {
    id: 'test-id',
    email: 'test@example.com',
    password: 'password123',
    name: 'Test User',
    role: UserRole.STUDENT,
    createdAt: new Date(),
    updatedAt: new Date(),
    isActive: true,
    ...overrides
  } as User;
}

export function createAuthUser(user: User): AuthUser {
  const { password: _, ...authUser } = user;
  return authUser as AuthUser;
}

export interface TestContext {
  prisma: PrismaClient;
  tokens: {
    admin: string;
    teacher: string;
    student: string;
  };
  users: {
    admin: User;
    teacher: User;
    student: User;
  };
}

export async function setupTestContext(): Promise<TestContext> {
  const prisma = (await import('../lib/prisma')).default;
  
  const admin = await prisma.user.create({
    data: createTestUser({ 
      email: 'admin@test.com', 
      role: UserRole.ADMIN,
      name: 'Test Admin' 
    })
  });

  const teacher = await prisma.user.create({
    data: createTestUser({ 
      email: 'teacher@test.com', 
      role: UserRole.TEACHER,
      name: 'Test Teacher' 
    })
  });

  const student = await prisma.user.create({
    data: createTestUser({ 
      email: 'student@test.com', 
      role: UserRole.STUDENT,
      name: 'Test Student' 
    })
  });

  return {
    prisma,
    tokens: {
      admin: createTestToken(admin),
      teacher: createTestToken(teacher),
      student: createTestToken(student)
    },
    users: {
      admin,
      teacher,
      student
    }
  };
}

export async function cleanupTestContext(ctx: TestContext): Promise<void> {
  const emails = [
    ctx.users.admin.email,
    ctx.users.teacher.email,
    ctx.users.student.email
  ];

  await ctx.prisma.user.deleteMany({
    where: {
      email: { in: emails }
    }
  });
}
